﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
using Microsoft.Win32;

namespace Jxym.Tools.RAR
{
    public class RarHelper
    {
        private string rarexe;      //WinRAR.exe 的完整路径
        private string _msg = "";   //返回消息
        public string Msg
        {
            get { return _msg; }
            set { _msg = value; }
        }

        public RarHelper()
        {
            try
            {
                RegistryKey regkey;  //注册表键
                Object regvalue;     //键值
                regkey = Registry.ClassesRoot.OpenSubKey(@"Applications\WinRAR.exe\shell\open\command");
                regvalue = regkey.GetValue("");
                rarexe = regvalue.ToString();
                regkey.Close();
                rarexe = rarexe.Substring(1, rarexe.Length - 7);
            }
            catch (Exception e)
            {
                _msg = e.Message;
            }
        }

        /// <summary>
        /// 利用 WinRAR 进行压缩 
        /// </summary>
        /// <param name="path">将要被压缩的文件夹（绝对路径）</param>
        /// <param name="rarPath">压缩后的 .rar 的存放目录（绝对路径）</param>
        /// <param name="rarName">压缩文件的名称（包括后缀）</param>
        /// <returns>true 或 false。压缩成功返回 true，反之，false。</returns>
        public bool RarCompress(string path, string rarPath, string rarName)
        {
            bool flag = false;
            string cmd;          //WinRAR 命令参数
            ProcessStartInfo startinfo;
            Process process;
            try
            {
                Directory.CreateDirectory(path);//压缩命令，相当于在要压缩的文件夹(path)上点右键 ->WinRAR->添加到压缩文件->输入压缩文件名(rarName)
                cmd = string.Format("a {0} {1} -r", rarName, path);
                startinfo = new ProcessStartInfo();
                startinfo.FileName = rarexe;
                startinfo.Arguments = cmd;                          //设置命令参数
                startinfo.WindowStyle = ProcessWindowStyle.Hidden;  //隐藏 WinRAR 窗口
                startinfo.WorkingDirectory = rarPath;
                process = new Process();
                process.StartInfo = startinfo;
                process.Start();
                process.WaitForExit(); //无限期等待进程 winrar.exe 退出
                if (process.HasExited)
                {
                    flag = true;
                    _msg = "压缩完成";
                }
                process.Close();
            }
            catch (Exception e)
            {
                _msg = e.Message;
            }
            return flag;
        }

        /// <summary>
        /// 利用 WinRAR 进行解压缩 
        /// </summary>
        /// <param name="path">文件解压路径（绝对）</param>
        /// <param name="rarPath">将要解压缩的 .rar 文件的存放目录（绝对路径）</param>
        /// <param name="rarName">将要解压缩的 .rar 文件名（包括后缀）</param>
        /// <returns>rue 或 false。解压缩成功返回 true，反之，false。</returns>
        public bool RarDeCompress(string path, string rarPath, bool deleteRarFile)
        {
            bool rv = false;
            try
            {
                //组合出需要shell的完整格式
                string shellArguments = string.Format("x -o+ \"{0}\" \"{1}\\\"", rarPath, path);
                //用Process调用
                using (Process unrar = new Process())
                {
                    unrar.StartInfo.FileName = rarexe;
                    unrar.StartInfo.Arguments = shellArguments;
                    //隐藏rar本身的窗口
                    unrar.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    unrar.Start();
                    //等待解压完成
                    unrar.WaitForExit();
                    unrar.Close();
                }
                //统计解压后的目录和文件数
                DirectoryInfo di = new DirectoryInfo(path);
                _msg = string.Format("解压完成，共解压出：{0}个目录，{1}个文件", di.GetDirectories().Length, di.GetFiles().Length);
                if (deleteRarFile)
                {
                    File.Delete(rarPath);
                }
                rv = true;
            }
            catch (Exception ex)
            {
                _msg = ex.Message;
            }
            return rv;
        }
    }
}
